﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Runtime;

namespace CuteAnt.Extension
{
	/// <summary>Xml扩展工具类</summary>
	/// <remarks></remarks>
	public static class XmlLinqUtils
	{
#if NET_2_3_5 || NET_3_5

		#region -- method CreateXDocumentFromStream --

		public static XDocument CreateXDocumentFromStream(Stream stream)
		{
			//return XDocument.Load(new StreamReader(stream), LoadOptions.None);
			return CreateXDocumentFromStream(stream, LoadOptions.None);
		}

		public static XDocument CreateXDocumentFromStream(Stream stream, LoadOptions options)
		{
			//return XDocument.Load(new StreamReader(stream), options);
			XmlReaderSettings xmlReaderSettings = GetXmlReaderSettings(options);
			XDocument result;
			using (XmlReader xmlReader = XmlReader.Create(stream, xmlReaderSettings))
			{
				result = XDocument.Load(xmlReader, options);
			}
			return result;
		}

		#endregion

		#region -- method CreateXElementFromStream --

		/// <summary>使用指定的流创建一个新的 XElement 实例。</summary>
		/// <param name="stream" type="System.IO.Stream">
		/// <para></para>
		/// </param>
		/// <returns>A System.Xml.Linq.XElement value...</returns>
		public static XElement CreateXElementFromStream(Stream stream)
		{
			return CreateXElementFromStream(stream, LoadOptions.None);
		}

		/// <summary>使用指定流创建新的 XElement 实例，也可以选择保留空白，设置基 URI 和保留行信息。</summary>
		/// <param name="stream" type="System.IO.Stream">
		/// <para></para>
		/// </param>
		/// <param name="options" type="System.Xml.Linq.LoadOptions">
		/// <para></para>
		/// </param>
		/// <returns>A System.Xml.Linq.XElement value...</returns>
		public static XElement CreateXElementFromStream(Stream stream, LoadOptions options)
		{
			XmlReaderSettings xmlReaderSettings = GetXmlReaderSettings(options);
			XElement result;
			using (XmlReader xmlReader = XmlReader.Create(stream, xmlReaderSettings))
			{
				result = XElement.Load(xmlReader, options);
			}
			return result;
		}

		// System.Xml.Linq.XNode
		private static XmlReaderSettings GetXmlReaderSettings(LoadOptions o)
		{
			XmlReaderSettings xmlReaderSettings = new XmlReaderSettings();
			if ((o & LoadOptions.PreserveWhitespace) == LoadOptions.None)
			{
				xmlReaderSettings.IgnoreWhitespace = true;
			}

			// NET_4_0
			//xmlReaderSettings.DtdProcessing = DtdProcessing.Parse;
			xmlReaderSettings.ProhibitDtd = false;
			xmlReaderSettings.MaxCharactersFromEntities = 10000000L;
			xmlReaderSettings.XmlResolver = null;
			return xmlReaderSettings;
		}

		#endregion

#endif
	}
}